﻿using CSRedis;
using IdentityModel;
using Lazy.Captcha.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using Rbac.Project.Utility;
using SmartHotel.Dto;
using SmartHotel.Users.Dto;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace SmartHotel.Users
{
    [ApiExplorerSettings(GroupName = "v1")]
    [Authorize]
    public class SmartHotelAppUserService : ApplicationService, ISmartHotelAppUserService
    {

        CSRedisClient _client = new CSRedisClient("127.0.0.1");

        private readonly IRepository<SmartHotel_UserTable, int> repository;
        private readonly IConfiguration configuration;
        private readonly ICaptcha _captcha;
        public SmartHotelAppUserService(IRepository<SmartHotel_UserTable, int> repository, IConfiguration Configuration, ICaptcha captcha)
        {
            this.repository = repository;
            configuration = Configuration;
            _captcha = captcha;
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [AllowAnonymous]
        public async Task<ResultDto<CreateUpdateUser>> CreateAsync(CreateUpdateUser model)
        {
            model.LoginPassword = Md5Helper.Md5(model.LoginPassword); 

            var list1 = ObjectMapper.Map<CreateUpdateUser, SmartHotel_UserTable>(model);

            var user=await repository.InsertAsync(list1);

            return new ResultDto<CreateUpdateUser> { Code = Result.Success, Message = "添加成功", Data = user };
        }
        /// <summary>
        /// 分页显示+模糊查
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>s
        /// <param name="userName"></param>
        /// <returns></returns>
        /// 
        [AllowAnonymous]
        public async Task<PageUserDto<UserDto>> GetHashCode(int pageIndex, int pageSize, string userName)
        {
            var data = await repository.GetListAsync();

            data = data.WhereIf(!string.IsNullOrEmpty(userName), x => x.UserName.Contains(userName)).ToList();
            var totalCount = data.Count();
            data = data.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            var dto = ObjectMapper.Map<List<SmartHotel_UserTable>, List<UserDto>>(data);
            return new PageUserDto<UserDto> { Code = Result.Success, Data = dto, totalCount = totalCount };
        }
        /// <summary>
        /// 获取验证码
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("ICaptcha")]
        [AllowAnonymous]
        public FileContentResult Captcha(string id)
        {
            var info = _captcha.Generate(id);
            var stream = new MemoryStream(info.Bytes);
            return new FileContentResult(stream.ToArray(), "image/gif");
        }
        /// <summary>
        /// 演示时使用HttpGet传参方便，这里仅做返回处理
        /// </summary>
        [HttpGet("validate")]
        public bool Validate(string id, string code)
        {
            return _captcha.Validate(id, code);
        }
        /// <summary>
        /// 多次校验（https://gitee.com/pojianbing/lazy-captcha/issues/I4XHGM）
        /// 演示时使用HttpGet传参方便，这里仅做返回处理
        /// </summary>
        [HttpPost("validate2")]
        [AllowAnonymous]
        public bool Validate2(string id, string code)
        {
            var rul= _captcha.Validate(id, code, false);
            return rul;
        }
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="loginPassword"></param>
        /// <returns></returns>
        [AllowAnonymous]
        public async Task<LoginResultDto> PostLoginAsync(LoginDto dto)
        {
            
            var user = await repository.GetAsync(m => m.LoginName == dto.LoginName);
            if (user == null)
            {
                return new LoginResultDto { Code = Result.Success, Message = "无此用户" };
            }
            else
            {
                if (user.LoginPassword.ToUpper() == dto.LoginPassword.Md5().ToUpper())
                {
                    //生成Token
                    //更新末次登录IP和末次登录时间


                    //身份信息认证
                    //写Session或Cookies换成JWT
                    IList<Claim> claims = new List<Claim> {
                        new Claim(JwtClaimTypes.Id,user.Id.ToString()),
                        new Claim(JwtClaimTypes.Name,user.LoginName),
                        new Claim(ClaimTypes.Name,user.LoginName),
                       // new Claim(ClaimTypes.Role,string.Join(',',roleIds))
                    };

                    //JWT密钥
                    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JwtConfig:Bearer:SecurityKey"]));

                    var cred = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                    //算法
                    //过期时间
                    DateTime expires = DateTime.UtcNow.AddHours(10);


                    //Payload负载
                    var token = new JwtSecurityToken(
                        issuer: configuration["JwtConfig:Bearer:Issuer"],
                        audience: configuration["JwtConfig:Bearer:Audience"],
                        claims: claims,
                        notBefore: DateTime.UtcNow,
                        expires: expires,
                        signingCredentials: cred
                        );

                    var handler = new JwtSecurityTokenHandler();

                    //生成令牌
                    string jwt = handler.WriteToken(token);
                    bool isCode = Validate2(dto.Id, dto.VerificationCode);
                    if (isCode)
                    {
                        return new LoginResultDto { Code = Result.Success, Message = "登录成功", Token = jwt };
                    }
                    else
                    {
                        return new LoginResultDto { Code = Result.Failed, Message = "验证码错误" };
                    }
                    
                }
                else
                {
                    return new LoginResultDto { Code = Result.Failed, Message = "密码不正确" };
                }
            }
        }

        /// <summary>
        /// 用户修改
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ResultDto<UserDto>> UpdateUser(CreateUpdateUser model)
        {
            var list = ObjectMapper.Map<CreateUpdateUser, SmartHotel_UserTable>(model);
            var data = await repository.UpdateAsync(list);
            if (data != null)
            {
                return new ResultDto<UserDto> { Code = Result.Success, Message = "修改成功" };
            }
            else
            {
                return new ResultDto<UserDto> { Code = Result.Failed, Message = "修改失败" };
            }
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// 

        [AllowAnonymous]
        public async Task<ResultDto<int>> DeleteUser(int id)
        {
            var data = await repository.FindAsync(id);
            await repository.DeleteAsync(data);
            return new ResultDto<int> { Code = Result.Success, Message = "删除成功" };
        }


    }
}
